package com.changan.utils;


import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: wmh
 * Create Time: 2021/5/27 15:38
 */
public class MysqlUtil {
    private String user = null;
    private String password = null;
    private String url = null;

    private static Connection conn = null;
    private static ResultSet resultSet = null;
    private static PreparedStatement preparedStatement = null;

    static {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static Connection getConnection(String url, String user, String password) {
        try {
            conn = DriverManager.getConnection(url, user, password);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return conn;
    }

    public static void closeAll(Connection conn, PreparedStatement preparedStatement, ResultSet resultSet) {
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                if (preparedStatement != null) {
                    try {
                        preparedStatement.close();
                    } catch (SQLException throwables) {
                        throwables.printStackTrace();
                    } finally {
                        if (conn != null) {
                            try {
                                conn.close();
                            } catch (SQLException throwables) {
                                throwables.printStackTrace();
                            }
                        }
                    }
                }
            }
        }
    }

    public static <T> List<T> resultToList(ResultSet resultSet, Class<T> clazz) {
        //创建一个 T 类型的数组
        List<T> list = new ArrayList<>();
        try {
            //通过反射获取对象的实例
            //获取resultSet 的列的信息
            ResultSetMetaData metaData = resultSet.getMetaData();
            //遍历resultSet
            while (resultSet.next()) {
                T t = clazz.getConstructor().newInstance();
                //遍历每一列
                for (int i = 0; i < metaData.getColumnCount(); i++) {
                    //获取列的名字
                    String sqlField = metaData.getColumnLabel(i + 1);
                    String fName = fieldToCamelCase(metaData.getColumnLabel(i + 1));
                    //因为列的名字和我们EMP中的属性名是一样的，所以通过列的名字获得其EMP中属性
                    Field field = null;
                    try {
                        field = clazz.getDeclaredField(fName);
                    } catch (Exception e) {
                        if (field == null) {
                            field = clazz.getSuperclass().getDeclaredField(fName);
                        }
                    }
                    //因为属性是私有的，所有获得其对应的set 方法。set+属性名首字母大写+其他小写
                    String setName = "set" + fName.toUpperCase().substring(0, 1) + fName.substring(1);
                    //因为属性的类型和set方法的参数类型一致，所以可以获得set方法
                    Method setMethod = clazz.getMethod(setName, field.getType());
                    //执行set方法，把resultSet中的值传入emp中，  再继续循环传值
                    //if (field.getType() == DataSyncStatus.class) {
                    //    setMethod.invoke(t, DataSyncStatus.valueOf(resultSet.getObject(sqlField).toString()));
                    //} else {
                    setMethod.invoke(t, resultSet.getObject(sqlField));
                    //}
                }
                //把赋值后的对象 加入到list集合中
                list.add(t);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        // 返回list
        return list;
    }

    public static <T> List<T> getDatas(PreparedStatement preparedStatement, Class clazz) throws SQLException {
        ResultSet resultSet = preparedStatement.executeQuery();
        List<T> list = resultToList(resultSet, clazz);
        MysqlUtil.closePreparedStatementAndResultset(preparedStatement, resultSet);
        return list;
    }

    public static void closePreparedStatementAndResultset(PreparedStatement preparedStatement, ResultSet resultSet) {
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                if (preparedStatement != null) {
                    try {
                        preparedStatement.close();
                    } catch (SQLException throwables) {
                        throwables.printStackTrace();
                    }
                }
            }
        }
    }

    public static void closeConnection(Connection connection) {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }

    /**
     * 下划线字段变为驼峰形式
     * a_b_c -> ABC
     * abc_def -> abcDef
     *
     * @param field 待转换字段
     * @return 驼峰形式字段
     */
    public static String fieldToCamelCase(String field) {
        if (field == null) {
            return null;
        }
        char[] charArray = field.toCharArray();
        String res = "";
        for (int i = 0; i < charArray.length; i++) {
            if (charArray[i] == '_') {
                i = i + 1;
                res += String.valueOf(charArray[i]).toUpperCase();
            } else {
                res += String.valueOf(charArray[i]);
            }
        }
        return res;
    }

}
